@ExceptionHandling에서 String을 반환하면 생기는 문제

Problem

Exception을 핸들링 해주는데 , 도메인에서 이름 값이 10자 넘어가는 경우 IllegalArgumentException을 발생시킴 하지만, ControllerAdvice에서 ResponseStatus 400으로 지정해서 Exception을 핸들링하는 경우 TemplateInputException이 발생해서 서버 500 에러가 뜸

대략 아래와 같은 형태였다.

@ExceptionHandling({IllegalArgumentException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleIllegalArgumentException(Exception exception){
	return exception.getMessage();
}

에러 메세지는 'Error resolving template [상품 이름은 10 글자를 넘을 수 없습니다]'과 같이 뜨는데, 이름 관련 예외 메세지는 도메인에서 정의된 것

Try

반환 타입을 String이 아닌 ResponseEntity<String>으로 한 다음 Status를 400을 반환 할 경우 400 결과를 받았다.

Reason

사실 Return type을 String으로만 해준 것이 문제였다. 만일 @ExceptionHandler에서 Return value를 String으로 해줄 경우, View Name으로 인식하여 ViewResolver에 의해 처리 된다. 따라서 Exception의 메세지로 된 템플릿은 없기 때문에 저런 에러 메세지가 난 것이였다.

Solution

따라서 @ExceptionHandler에 RESTful한 응답을 주고 싶다면, ResponseEntity<String>의 형태로 반환을 해주자.

Additional

Response로 DTO 객체를 바로 반환할 경우 자동으로 직렬화되었다. 이유는?

원래 @ResponseBody 어노테이션이 붙은 메서드는 반환객체를 HttpMessageConverter를 통해 직렬화를 한다.

@RestController@Controller@ResponseBody를 표시한 메타주석이기 때문에, @RestController에서 Serialize 가능한 객체를 반환하면 직렬화가 된다.